import { join, relative } from 'path';
import { writeFileSync, mkdirSync, readdirSync, readFileSync, existsSync } from 'fs';

interface ExampleConfig {
  id: string;
  name: string;
  description: string;
  order: number;
  flow: string;
  files: Array<{
    name: string;
    description: string;
  }>;
}

interface PlaygroundExample {
  id: string;
  name: string;
  description: string;
  order: number;
  flow: any;
  files: Array<{
    name: string;
    type: 'flyde' | 'ts';
    content: string;
    description: string;
  }>;
}

const examplesDir = join(__dirname, '../playground-examples');
const distDir = join(__dirname, '../lib/generated');

// Create dist directory if it doesn't exist
mkdirSync(distDir, { recursive: true });

console.log('🔨 Building playground examples...');

// Read all example directories
const exampleDirs = readdirSync(examplesDir, { withFileTypes: true })
  .filter(dirent => dirent.isDirectory())
  .map(dirent => dirent.name);

const playgroundExamples: PlaygroundExample[] = [];

// Process each example
for (const exampleDir of exampleDirs) {
  const examplePath = join(examplesDir, exampleDir);
  const configPath = join(examplePath, 'config.json');
  
  if (!existsSync(configPath)) {
    console.warn(`⚠️  No config.json found for example: ${exampleDir}`);
    continue;
  }

  console.log(`📁 Processing ${exampleDir}...`);
  
  // Read example config
  const config: ExampleConfig = JSON.parse(readFileSync(configPath, 'utf8'));
  
  // Read the raw flow file (don't resolve at build time - resolve at runtime for custom nodes)
  const flowPath = join(examplePath, config.flow);
  if (!existsSync(flowPath)) {
    console.error(`❌ Flow file not found: ${config.flow} in ${exampleDir}`);
    continue;
  }
  
  // Read raw YAML/JSON content instead of using resolveFlowByPath which does resolution
  const rawFlowContent = readFileSync(flowPath, 'utf8');
  let rawFlowNode;
  
  try {
    // Parse YAML flow file to get raw structure
    const flowData = require('yaml').parse(rawFlowContent);
    rawFlowNode = flowData.node || flowData; // Get the node part of the flow
  } catch (e) {
    console.error(`❌ Failed to parse flow file ${config.flow}:`, e);
    continue;
  }
  
  // Read all files mentioned in config
  const files = [];
  for (const fileConfig of config.files) {
    const filePath = join(examplePath, fileConfig.name);
    if (!existsSync(filePath)) {
      console.warn(`⚠️  File not found: ${fileConfig.name} in ${exampleDir}`);
      continue;
    }
    
    const content = readFileSync(filePath, 'utf8');
    const type = fileConfig.name.endsWith('.flyde') ? 'flyde' : 'ts';
    
    // For .flyde files, convert YAML to JSON format that matches the editor
    let finalContent = content;
    if (type === 'flyde') {
      try {
        const flowData = require('yaml').parse(content);
        const nodeData = flowData.node || flowData;
        finalContent = JSON.stringify(nodeData, null, 2);
      } catch (e) {
        console.warn(`⚠️  Could not convert ${fileConfig.name} to JSON format, keeping original`);
      }
    }
    
    files.push({
      name: fileConfig.name,
      type: type as 'flyde' | 'ts',
      content: finalContent,
      description: fileConfig.description
    });
  }
  
  playgroundExamples.push({
    id: config.id,
    name: config.name,
    description: config.description,
    order: config.order,
    flow: rawFlowNode,
    files
  });
  
  console.log(`✅ Built ${config.name} with ${files.length} files`);
}

// Sort examples by order
playgroundExamples.sort((a, b) => a.order - b.order);

// Generate the playground config
const configContent = `// This file is auto-generated by build-playground-examples.ts
// Do not edit directly - edit files in /playground-examples instead

export interface PlaygroundExample {
  id: string;
  name: string;
  description: string;
  order: number;
  flow: any;
  files: Array<{
    name: string;
    type: 'flyde' | 'ts';
    content: string;
    description: string;
  }>;
}

export const playgroundExamples: PlaygroundExample[] = ${JSON.stringify(playgroundExamples, null, 2)};

export function getExampleById(id: string): PlaygroundExample | undefined {
  return playgroundExamples.find(example => example.id === id);
}

export function getExamplesList(): { id: string; name: string; description: string }[] {
  return playgroundExamples.map(({ id, name, description }) => ({ id, name, description }));
}

export function getExampleFiles(id: string): PlaygroundExample['files'] {
  const example = getExampleById(id);
  return example?.files || [];
}
`;

const outputPath = join(distDir, 'playground-examples.ts');
writeFileSync(outputPath, configContent);

console.log(`🎉 Generated playground config with ${playgroundExamples.length} examples`);
console.log(`📝 Output: ${relative(process.cwd(), outputPath)}`);

